home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / demos / OpenGL / space / fract.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  39KB  |  1,173 lines

  1. /*
  2.  * Copyright (C) 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include <GL/gl.h>
  19. #include <math.h>
  20. #include "space.h"
  21.  
  22. #define LOWER_TRI        1
  23. #define UPPER_TRI        2
  24. #define BOTHH_TRI        3
  25.  
  26. #define LEVEL_SEA        1.00 
  27. #define LEVEL_SNOW       1.02 
  28.  
  29. #define MAT_SEABLUE      0 
  30. #define MAT_DIRT         1 
  31. #define MAT_WHITE        2 
  32. #define SUM_WHITE        6 
  33. #define SUM_SEABLUE      0 
  34.  
  35. #define SUBDIVIDE(aa,bb,cc)                    \
  36.          x = (aa)->plan.x + (bb)->plan.x ;             \
  37.          y = (aa)->plan.y + (bb)->plan.y ;             \
  38.          z = (aa)->plan.z + (bb)->plan.z ;             \
  39.          w = fsqrt(x*x+y*y+z*z) ;                \
  40.                                 \
  41.          if (Counter.flags & FRACT_FLAG) {            \
  42.            (cc)->seed = (aa)->seed + (bb)->seed ;        \
  43.            srand((cc)->seed) ;                    \
  44.            s = rand() - 16384 ;                    \
  45.            (cc)->delta = 0.5*((aa)->delta+(bb)->delta) + rg*(flot32)s ;\
  46.            w = (cc)->delta / w;                    \
  47.            }                            \
  48.          else  {                        \
  49.            p.x = x ;                        \
  50.            p.y = y ;                        \
  51.            p.z = z ;                        \
  52.            (cc)->seed = convert(&p) ;                \
  53.            (cc)->delta = p.w ;                    \
  54.            w = (cc)->delta / w;                    \
  55.            }                            \
  56.                                 \
  57.          (cc)->plan.x = w*x ;                    \
  58.          (cc)->plan.y = w*y ;                    \
  59.          (cc)->plan.z = w*z ;                    \
  60.  
  61. typedef struct  {
  62.        sint32 ar,ag,ab   ;
  63.        flot32 dr,dg,db   ; 
  64. } C6 ;
  65.  
  66. static C6 a_dirt,a_seab,a_whit ;
  67.  
  68. typedef struct  {                 /* 284 BYTES */
  69.        P3        p ;
  70.        uint32    seed ;    
  71.        sint16    valid ;
  72.        sint16    quadw ;
  73.        V4        v0[5] ;
  74.        V4        v1[5] ;
  75.        P3        pp[8] ;
  76.        TrigPoint *sur ;
  77. } P5 ;
  78.  
  79. typedef struct  {
  80.        V4      v1[5] ;
  81.        V4      v2[5] ;
  82. } Bounder ;
  83.  
  84. extern t_stopwatch Counter ;
  85. extern P4      feye ;
  86. extern V3      lit ;
  87. extern flot32  vids ;
  88. extern t_body  *planet ;
  89. extern V4      plum[NUM_CLIP_PLANES] ;
  90.  
  91. static sint32  dbg[8] ;
  92. static sint32  levels,sidsz ;
  93. static sint32  A,B,C ;
  94. static flot32  roughness = 0.05 ;
  95. static P5      dt[33][33] ;
  96. static struct  { sint32 status,xi,yi,flag ; }  status ;
  97.  
  98. static Bounder checkcrash[33][33] ;
  99.  
  100. static void   fract_mid(sint32,sint32,sint32,sint32,flot32) ;
  101. static void   create_continent(P5 *,sint32,sint32) ;
  102. static void   destroy_continent(P5 *) ;
  103. static void   bound_normals(P3 *,P3 *,P3 *,V4 *) ;
  104. static sint32 clipp(P5 *) ;
  105. static void   land_generation(P5 *,sint32) ;
  106. static void   water_conversion(P5 *,sint32) ;
  107. static void   generate_shades(P5 *,sint32) ;
  108. static void   cpack_continent(P5 *,uint32) ;
  109. static void   intersect_continent(void) ;
  110. static void   enhanced_bound_normals(P5 *,sint32) ;
  111. static void   p_trigpoint(TrigPoint *) ;
  112. static void   p_continent(P5 *) ;
  113. static uint32 convert(P4 *) ;
  114. extern uint32 converu(P4 *) ;
  115.  
  116. /**********************************************************************
  117. *  convert()  -
  118. **********************************************************************/
  119. static uint32 convert(register P4 *p) 
  120.  
  121. {  register flot32 the,phi,s,t ;
  122.    register sint32 i,data,q ;
  123.    register sint16 *r ;
  124.    register unsigned char c ;
  125.  
  126.    if ((planet->ptr->lformat>>4) & 0x1)
  127.      return(converu(p));
  128.  
  129.    if (p->x == 0.0 && p->z == 0.0)
  130.      p->x += 0.000001 ;
  131.  
  132.    the = fatan2(p->z,p->x) ;
  133.    phi = fatan2(p->y,fsqrt(p->x*p->x + p->z*p->z)) ;
  134.  
  135.    switch (planet->ptr->lformat&0xf)  {
  136.      case FM_MERC_1B :
  137.         t = (flot32) planet->ptr->lysize * (0.5 + phi/M_PI) ;
  138.         s = (flot32) planet->ptr->lxsize * (0.5 - 0.5*the/M_PI) ;
  139.         i = t ; i *= planet->ptr->lxsize ; i += s ;
  140.         p->w = 1.0 + planet->ptr->scale*(flot32)planet->land[i] ;
  141.         break ;
  142.      case FM_MERC_2B :
  143.         t = (flot32) planet->ptr->lysize * (0.5 + phi/M_PI) ;
  144.         s = (flot32) planet->ptr->lxsize * (0.5 - 0.5*the/M_PI) ;
  145.         i = t ; i *= 2*planet->ptr->lxsize ; i += 2*(sint32)s ;
  146.         r = (sint16 *) &planet->land[i] ;
  147.         p->w = 1.0 + planet->ptr->scale*(flot32)*r ;
  148.         break ;
  149.      case FM_MERC_4B :
  150.         t = (flot32) planet->ptr->lysize * (0.5 + phi/M_PI) ;
  151.         s = (flot32) planet->ptr->lxsize * (0.5 - 0.5*the/M_PI) ;
  152.         i = t ; i *= 4*planet->ptr->lxsize ; i += 4*(sint32)s ;
  153.         q = *(sint32 *) &planet->land[i] ;
  154.         data = (q & 0x00ffffff) | 0xff000000 ;
  155.         i = (q >> 24) & 0x000000ff ;
  156.         p->w = 1.0 + planet->ptr->scale*(flot32)i ;
  157.         return(data) ;
  158.         break ;
  159.      case FM_SINU_1B :
  160.         t = (flot32) planet->ptr->lysize * (0.5 + phi/M_PI) ;
  161.         s = (flot32) planet->ptr->lxsize * (0.5 - 0.5*the*fcos(phi)/M_PI) ;
  162.         i = t ; i *= planet->ptr->lxsize ; i += s ;
  163.         p->w = 1.0 + planet->ptr->scale*(flot32)planet->land[i] ;
  164.         break ;
  165.      case FM_SINU_2B :
  166.         t = (flot32) planet->ptr->lysize * (0.5 + phi/M_PI) ;
  167.         s = (flot32) planet->ptr->lxsize * (0.5 - 0.5*the*fcos(phi)/M_PI) ;
  168.         i = t ; i *= 2*planet->ptr->lxsize ; i += 2*(sint32)s ;
  169.         r = (sint16 *) &planet->land[i] ;
  170.         p->w = 1.0 + planet->ptr->scale*(flot32)*r ;
  171.         break ;
  172.      case FM_SINU_4B :
  173.         t = (flot32) planet->ptr->lysize * (0.5 + phi/M_PI) ;
  174.         s = (flot32) planet->ptr->lxsize * (0.5 - 0.5*the*fcos(phi)/M_PI) ;
  175.         i = t ; i *= 4*planet->ptr->lxsize ; i += 4*(sint32)s ;
  176.         q = *(sint32 *) &planet->land[i] ;
  177.         data = (q & 0x00ffffff) | 0xff000000 ;
  178.         i = (q >> 24) & 0x000000ff ;
  179.         p->w = 1.0 + planet->ptr->scale*(flot32)i ;
  180.         return(data) ;
  181.         break ;
  182.      default:
  183.         exit(0) ;
  184.         break ;
  185.      }
  186.  
  187.    switch (planet->ptr->cformat&0xf)  {
  188.      case FM_MERC_1B :
  189.         t = (flot32) planet->ptr->cysize * (0.5 + phi/M_PI) ;
  190.         s = (flot32) planet->ptr->cxsize * (0.5 - 0.5*the/M_PI) ;
  191.         i = t ; i *= planet->ptr->cxsize ; i += s ;
  192.         c = planet->colr[i] ;
  193.         data = 0xff000000 | ((c<<14)&0xff0000) | ((c<<7)&0x00ff00) | c ;
  194.         break ;
  195.      case FM_MERC_3B :
  196.         t = (flot32) planet->ptr->cysize * (0.5 + phi/M_PI) ;
  197.         s = (flot32) planet->ptr->cxsize * (0.5 - 0.5*the/M_PI) ;
  198.         i = t ; i *= 4*planet->ptr->cxsize ; i += 4*(sint32)s ;
  199.         data = *(sint32 *)&planet->colr[i] ;
  200.         break ;
  201.      case FM_SINU_1B :
  202.         t = (flot32) planet->ptr->cysize * (0.5 + phi/M_PI) ;
  203.         s = (flot32) planet->ptr->cxsize * (0.5 - 0.5*the*fcos(phi)/M_PI) ;
  204.         i = t ; i *= planet->ptr->cxsize ; i += s ;
  205.         c = planet->colr[i] ;
  206.         data = 0xff000000 | ((c<<14)&0xff0000) | ((c<<7)&0x00ff00) | c ;
  207.         break ;
  208.      case FM_SINU_3B :
  209.         t = (flot32) planet->ptr->cysize * (0.5 + phi/M_PI) ;
  210.         s = (flot32) planet->ptr->cxsize * (0.5 - 0.5*the*fcos(phi)/M_PI) ;
  211.         i = t ; i *= 3*planet->ptr->cxsize ; i += 3*(sint32)s ;
  212.         data = *(sint32 *)&planet->colr[i] ;
  213.         break ;
  214.      default:
  215.         break ;
  216.      }
  217.  
  218.    return(data) ;
  219. }
  220.  
  221. /**********************************************************************
  222. *  fract_mid()  -
  223. **********************************************************************/
  224. static void fract_mid(sint32 x1,sint32 y1,sint32 x2,sint32 y2,flot32 rough)
  225.  
  226. {  register sint32  xi,yi,s,seed ;
  227.    register flot32  x,y,z,w[4] ;
  228.    register P5      *d,*d1,*d2 ;
  229.    register P4      p ;
  230.  
  231.    xi = (x1 + x2) >> 1 ;
  232.    yi = (y1 + y2) >> 1 ;
  233.  
  234.    d  = &dt[yi][xi] ;
  235.    d1 = &dt[y1][x1] ;
  236.    d2 = &dt[y2][x2] ;
  237.  
  238.    x = d1->p.x + d2->p.x ;
  239.    y = d1->p.y + d2->p.y ;
  240.    z = d1->p.z + d2->p.z ;
  241.  
  242.    w[0] = fsqrt(x*x+y*y+z*z) ;
  243.  
  244.    if (Counter.flags & FRACT_FLAG) {
  245.      w[1] = fsqrt(d1->p.x*d1->p.x + d1->p.y*d1->p.y + d1->p.z*d1->p.z) ;
  246.      w[2] = fsqrt(d2->p.x*d2->p.x + d2->p.y*d2->p.y + d2->p.z*d2->p.z) ;
  247.      d->seed = d1->seed + d2->seed ;
  248.      srand(d->seed) ;
  249.      s = rand() - 16384 ;
  250.      w[3] = (0.5*(w[1]+w[2]) + rough*(float)s/16384.0) / w[0] ;
  251.      }
  252.    else  {
  253.      p.x = x ;
  254.      p.y = y ;
  255.      p.z = z ;
  256.      d->seed = convert(&p) ;
  257.      w[3] = p.w / w[0] ;
  258.      }
  259.  
  260.    d->p.x = w[3]*x ;
  261.    d->p.y = w[3]*y ;
  262.    d->p.z = w[3]*z ;
  263. }
  264.  
  265. /**********************************************************************
  266. *  generate_fractsphere()  -
  267. **********************************************************************/
  268. void generate_fractsphere(sint32 level,sint32 in_seed) 
  269.  
  270. {  register flot32  x,y,z,w,e[6],delta0,delta1,delta2,delta3 ;
  271.    register sint32  i,j,stage,step,dstep,even ;
  272.    register P4      q ;
  273.    register P5      *d,*p0,*p1,*p2,*p3 ;
  274.    register P3      *pp ;
  275.  
  276.    if (Counter.flags & FRACT_FLAG)  {
  277.      a_dirt.ar = 5; a_dirt.ag = 4; a_dirt.ab = 2; a_dirt.dr = 155.0; a_dirt.dg = 140.0; a_dirt.db =  70.0; 
  278.      a_seab.ar = 0; a_seab.ag = 0; a_seab.ab = 5; a_seab.dr =   0.0; a_seab.dg =   0.0; a_seab.db = 224.0; 
  279.      a_whit.ar = 5; a_whit.ag = 5; a_whit.ab = 5; a_whit.dr = 250.0; a_whit.dg = 250.0; a_whit.db = 250.0; 
  280.      }
  281.  
  282.    if (level < 0 || level > 4)
  283.      exit(0) ;
  284.  
  285.    levels = -1 ;
  286.  
  287.    srand(in_seed) ;
  288.  
  289.    for (C=level,B=2,A=1,i=0; i<level; A=B,B<<=1,i++) ;
  290.  
  291.    if (Counter.flags & FRACT_FLAG)  {
  292.      for (i=0; i<6; i+=2)  {
  293.        j = rand() - 16384 ;
  294.      
  295.        e[i  ] = -1.0 + 0.2*roughness*(flot32)j/16384.0 ;
  296.        e[i+1] =  1.0 + 0.2*roughness*(flot32)j/16384.0 ;
  297.        }
  298.  
  299.      d = &dt[0][0]; d->p.x =    0; d->p.y = e[0]; d->p.z =    0; d->seed = rand();
  300.      d = &dt[0][A]; d->p.x =    0; d->p.y =    0; d->p.z = e[4]; d->seed = rand();
  301.      dt[0][B] = dt[0][0] ;
  302.      d = &dt[A][0]; d->p.x = e[2]; d->p.y =    0; d->p.z =    0; d->seed = rand();
  303.      d = &dt[A][A]; d->p.x =    0; d->p.y = e[1]; d->p.z =    0; d->seed = rand();
  304.      d = &dt[A][B]; d->p.x = e[3]; d->p.y =    0; d->p.z =    0; d->seed = rand();
  305.      dt[B][0] = dt[0][0] ;
  306.      d = &dt[B][A]; d->p.x =    0; d->p.y =    0; d->p.z = e[5]; d->seed = rand();
  307.      dt[B][B] = dt[0][0] ;
  308.      }
  309.    else  {
  310.      d = &dt[0][0]; q.x =    0; q.y = -1.0; q.z =    0; d->seed = convert(&q) ;
  311.      d->p.x = q.x*q.w; d->p.y = q.y*q.w; d->p.z = q.z*q.w;
  312.      d = &dt[0][A]; q.x =    0; q.y =    0; q.z = -1.0; d->seed = convert(&q) ;
  313.      d->p.x = q.x*q.w; d->p.y = q.y*q.w; d->p.z = q.z*q.w;
  314.      d = &dt[0][B]; q.x =    0; q.y = -1.0; q.z =    0; d->seed = convert(&q) ;
  315.      d->p.x = q.x*q.w; d->p.y = q.y*q.w; d->p.z = q.z*q.w;
  316.      d = &dt[A][0]; q.x = -1.0; q.y =    0; q.z =    0; d->seed = convert(&q) ;
  317.      d->p.x = q.x*q.w; d->p.y = q.y*q.w; d->p.z = q.z*q.w;
  318.      d = &dt[A][A]; q.x =    0; q.y =  1.0; q.z =    0; d->seed = convert(&q) ;
  319.      d->p.x = q.x*q.w; d->p.y = q.y*q.w; d->p.z = q.z*q.w;
  320.      d = &dt[A][B]; q.x =  1.0; q.y =    0; q.z =    0; d->seed = convert(&q) ;
  321.      d->p.x = q.x*q.w; d->p.y = q.y*q.w; d->p.z = q.z*q.w;
  322.      d = &dt[B][0]; q.x =    0; q.y = -1.0; q.z =    0; d->seed = convert(&q) ;
  323.      d->p.x = q.x*q.w; d->p.y = q.y*q.w; d->p.z = q.z*q.w;
  324.      d = &dt[B][A]; q.x =    0; q.y =    0; q.z =  1.0; d->seed = convert(&q) ;
  325.      d->p.x = q.x*q.w; d->p.y = q.y*q.w; d->p.z = q.z*q.w;
  326.      d = &dt[B][B]; q.x =    0; q.y = -1.0; q.z =    0; d->seed = convert(&q) ;
  327.      d->p.x = q.x*q.w; d->p.y = q.y*q.w; d->p.z = q.z*q.w;
  328.      }
  329.  
  330.    for (step=A/2,dstep=A,stage=1; stage<=level; dstep=step,step>>=1,stage++)
  331.      for (i=dstep; i<=B; i+=dstep)
  332.        for (j=step; j<=B; j+=dstep)  {
  333.           fract_mid(j-step,i      ,j+step,i      ,(flot32)roughness/stage) ; 
  334.           fract_mid(j-step,i-dstep,j+step,i-dstep,(flot32)roughness/stage) ; 
  335.           fract_mid(j-step,i      ,j-step,i-dstep,(flot32)roughness/stage) ; 
  336.           fract_mid(j+step,i      ,j+step,i-dstep,(flot32)roughness/stage) ; 
  337.  
  338.           if ((((i-dstep)&A)+((j-step)&A)) & A)
  339.                fract_mid(j-step,i-dstep,j+step,i      ,(flot32)roughness/stage) ;
  340.           else fract_mid(j-step,i      ,j+step,i-dstep,(flot32)roughness/stage) ;
  341.           }
  342.  
  343.    for (i=0; i<B; i++)
  344.      for (j=0; j<B; j++)  {
  345.        dt[i][j].valid = 0 ;
  346.        dt[i][j].quadw = 0 ;
  347.        dt[i][j].sur = 0 ;
  348.  
  349.        if (((i&A)+(j&A)) & A)  {
  350.          bound_normals(&dt[i][j].p,&dt[i][j+1].p,&dt[i+1][j+1].p,&dt[i][j].v0[0]) ;
  351.          bound_normals(&dt[i][j].p,&dt[i+1][j].p,&dt[i+1][j+1].p,&dt[i][j].v1[0]) ;
  352.          }
  353.        else  {
  354.          bound_normals(&dt[i][j].p,&dt[i][j+1].p,&dt[i+1][j].p,&dt[i][j].v0[0]) ;
  355.          bound_normals(&dt[i+1][j+1].p,&dt[i][j+1].p,&dt[i+1][j].p,&dt[i][j].v1[0]) ;
  356.          }
  357.  
  358.        even = ((((j&A)+(i&A)) & A) ? 1 : 0) ;
  359.  
  360.        if (!even)  {
  361.          p0 = &dt[i+0][j+0] ;
  362.          p1 = &dt[i+0][j+1] ;
  363.          p2 = &dt[i+1][j+0] ;
  364.          p3 = &dt[i+1][j+1] ;
  365.          }
  366.        else  {
  367.          p0 = &dt[i+0][j+1] ;
  368.          p1 = &dt[i+1][j+1] ;
  369.          p2 = &dt[i+0][j+0] ;
  370.          p3 = &dt[i+1][j+0] ;
  371.          }
  372.  
  373.        delta0 = fsqrt(p0->p.x*p0->p.x + p0->p.y*p0->p.y + p0->p.z*p0->p.z);
  374.        delta1 = fsqrt(p1->p.x*p1->p.x + p1->p.y*p1->p.y + p1->p.z*p1->p.z);
  375.        delta2 = fsqrt(p2->p.x*p2->p.x + p2->p.y*p2->p.y + p2->p.z*p2->p.z);
  376.        delta3 = fsqrt(p3->p.x*p3->p.x + p3->p.y*p3->p.y + p3->p.z*p3->p.z);
  377.   
  378.        pp = dt[i][j].pp ;
  379.        pp[0].x = p0->p.x/delta0 ; pp[0].y = p0->p.y/delta0 ; pp[0].z = p0->p.z/delta0 ;
  380.        pp[2].x = p1->p.x/delta1 ; pp[2].y = p1->p.y/delta1 ; pp[2].z = p1->p.z/delta1 ;
  381.        pp[4].x = p2->p.x/delta2 ; pp[4].y = p2->p.y/delta2 ; pp[4].z = p2->p.z/delta2 ;
  382.        pp[6].x = p3->p.x/delta3 ; pp[6].y = p3->p.y/delta3 ; pp[6].z = p3->p.z/delta3 ;
  383.   
  384.        pp[1].x = 1.25*pp[0].x ; pp[1].y = 1.25*pp[0].y ; pp[1].z = 1.25*pp[0].z ;
  385.        pp[3].x = 1.25*pp[2].x ; pp[3].y = 1.25*pp[2].y ; pp[3].z = 1.25*pp[2].z ;
  386.        pp[5].x = 1.25*pp[4].x ; pp[5].y = 1.25*pp[4].y ; pp[5].z = 1.25*pp[4].z ;
  387.        pp[7].x = 1.25*pp[6].x ; pp[7].y = 1.25*pp[6].y ; pp[7].z = 1.25*pp[6].z ;
  388.        }
  389.  
  390.    status.status = -1 ;
  391.    status.xi = 0 ;
  392.    status.yi = 0 ;
  393.    status.flag = 0 ;
  394. }
  395.  
  396. /**********************************************************************
  397. *  display_fractsphere()  -
  398. **********************************************************************/
  399. void display_fractsphere(void) 
  400.  
  401. {  register sint32 i,j,flag ;
  402.    register uint32 hey ;
  403.    register flot32 vian ;
  404.    register P5     *p ;
  405.    register V4     *v ;
  406.    register V3     fevt ;
  407.  
  408.    for (i=0; i<8; i++)
  409.      dbg[i] = 0 ;
  410.  
  411.    if (Counter.flags & FRACT_FLAG)
  412.      vian = 1.0/(vids+1.0) - 0.040 ;
  413.    else vian = 1.0/(vids+1.0) - 0.025 ;
  414.  
  415.    fevt.x = feye.x/feye.w ;
  416.    fevt.y = feye.y/feye.w ;
  417.    fevt.z = feye.z/feye.w ;
  418.  
  419.         if (vids > 64.00) i = 0+Counter.hw_graphics ;
  420.    else if (vids > 16.00) i = 1+Counter.hw_graphics ;
  421.    else if (vids >  4.00) i = 2+Counter.hw_graphics ;
  422.    else if (vids >  1.00) i = 3+Counter.hw_graphics ;
  423.    else if (vids >  0.25) i = 4+Counter.hw_graphics ;
  424.    else                   i = 5+Counter.hw_graphics ;
  425.  
  426.    if (i < 0) i = 0 ;
  427.    if (i > 6) i = 6 ;
  428.  
  429.    if (i != levels)  {
  430.      Counter.flags |= FREEZ_FLAG ;
  431.      levels = i ;
  432.      for (j=1,i=0; i<levels; j<<=2,i++) ;
  433.      printf("New Level: %d, Triangles: 2048*%d\n",i,j) ;
  434.      status.status = -1 ;
  435.  
  436.      for (i=0; i<B; i++)
  437.        for (p=dt[i],j=0; j<B; p++,j++)
  438.           destroy_continent(p) ;
  439.      }
  440.  
  441.    for (sidsz=1,i=0; i<levels; sidsz<<=1,i++) ;
  442.  
  443.    /* are we still on the home plate */
  444.    if (status.status == 1)  {
  445.      status.status = 0 ;
  446.      v = (status.flag ? &dt[status.yi][status.xi].v1[0] : &dt[status.yi][status.xi].v0[0]) ;
  447.  
  448.      if (v[0].x*feye.x + v[0].y*feye.y + v[0].z*feye.z >= 0.0)
  449.        if (v[1].x*feye.x + v[1].y*feye.y + v[1].z*feye.z >= 0.0)
  450.          if (v[2].x*feye.x + v[2].y*feye.y + v[2].z*feye.z >= 0.0)
  451.            status.status = 1 ;
  452.      }
  453.  
  454.    /* find and create new new home plate */
  455.    if (status.status != 1)
  456.      for (i=0; i<B; i++)
  457.        for (p=dt[i],j=0; j<B; p++,j++)  {
  458.          if (p->v0[0].x*feye.x + p->v0[0].y*feye.y + p->v0[0].z*feye.z >= 0.0)
  459.            if (p->v0[1].x*feye.x + p->v0[1].y*feye.y + p->v0[1].z*feye.z >= 0.0)
  460.              if (p->v0[2].x*feye.x + p->v0[2].y*feye.y + p->v0[2].z*feye.z >= 0.0)  {
  461.                status.xi = j ;
  462.                status.yi = i ;
  463.                status.flag = 0 ;
  464.  
  465.                if (flag = (LOWER_TRI & ~p->valid) & BOTHH_TRI) 
  466.                  create_continent(p,flag,((((j&A)+(i&A)) & A) ? 1 : 0)) ;
  467.  
  468.                status.status = 1 ;
  469.                enhanced_bound_normals(p,LOWER_TRI) ;
  470.  
  471.                dbg[7]++ ;
  472.                goto d_FOUND ;
  473.                }
  474.  
  475.          if (p->v1[0].x*feye.x + p->v1[0].y*feye.y + p->v1[0].z*feye.z >= 0.0)
  476.            if (p->v1[1].x*feye.x + p->v1[1].y*feye.y + p->v1[1].z*feye.z >= 0.0)
  477.              if (p->v1[2].x*feye.x + p->v1[2].y*feye.y + p->v1[2].z*feye.z >= 0.0) {
  478.                status.xi = j ;
  479.                status.yi = i ;
  480.                status.flag = 1 ;
  481.  
  482.                if (flag = (UPPER_TRI & ~p->valid) & BOTHH_TRI) 
  483.                  create_continent(p,flag,((((j&A)+(i&A)) & A) ? 1 : 0)) ;
  484.  
  485.                status.status = 1 ;
  486.                enhanced_bound_normals(p,UPPER_TRI) ;
  487.  
  488.                dbg[7]++ ;
  489.                goto d_FOUND ;
  490.                }
  491.          }
  492.  
  493. d_FOUND: i = i ;
  494.  
  495.    /* generate new plates, destroy old plates, draw valid plates */
  496.    for (i=0; i<B; i++)
  497.      for (p=dt[i],j=0; j<B; p++,j++)  {
  498.        flag = 0 ;
  499.  
  500.        v = &p->v0[4] ;
  501.        if (v->x*fevt.x + v->y*fevt.y + v->z*fevt.z > vian) 
  502.          flag |= LOWER_TRI ;
  503.  
  504.        v = &p->v1[4] ;
  505.        if (v->x*fevt.x + v->y*fevt.y + v->z*fevt.z > vian)
  506.          flag |= UPPER_TRI ;
  507.  
  508.        if (flag)  {
  509.          if (flag = (flag & ~p->valid) & BOTHH_TRI)
  510.            create_continent(p,flag,((((j&A)+(i&A)) & A) ? 1 : 0)) ;
  511.  
  512.          if (p->sur)  {
  513.            flag = p->valid & clipp(p) ;
  514.            if (Counter.flags & SHADE_FLAG)
  515.              generate_shades(p,flag) ;
  516.            cpack_continent(p,flag) ;
  517.            }
  518.          }
  519.        else if (p->sur)  {
  520.          hey = (uint32)p->sur ;
  521.          free(hey - (p->quadw) ? 0 : 8) ;
  522.  
  523.          p->valid = 0 ;
  524.          p->quadw = 0 ;
  525.          p->sur = 0 ;
  526.          }
  527.        }
  528.  
  529.    /* intersect home plate */
  530.    intersect_continent() ;
  531.  
  532.    if ((Counter.flags & PRINT_FLAG) && (dbg[0]+dbg[1]+dbg[7]))
  533.      printf("Create: %d/%d Display: %02d/%02d Enhance: %d\n",dbg[0],dbg[1],dbg[2],dbg[3],dbg[7]) ;
  534. }
  535.  
  536. /**********************************************************************
  537. *  destroy_fractsphere()  -
  538. **********************************************************************/
  539. void destroy_fractsphere(void) 
  540.  
  541. {  register sint32 i,j ;
  542.    register P5     *p ;
  543.  
  544.    for (i=0; i<B; i++)
  545.      for (p=dt[i],j=0; j<B; p++,j++)
  546.         destroy_continent(p) ;
  547. }
  548.  
  549. /**********************************************************************
  550. *  create_continent()  - 
  551. **********************************************************************/
  552. static void create_continent(register P5 *d,register sint32 create,sint32 even)
  553.  
  554. {  register sint32     cstat,size ;
  555.    register sint32     hey ;
  556.    register TrigPoint  *sur,*p0,*p1,*p2,*p3 ;
  557.    register P3         *p ;
  558.    register flot32     w ;
  559.  
  560.    cstat = clipp(d) ;
  561.  
  562.    if (status.status == 1)
  563.      create &= cstat ;
  564.  
  565.    if (!create)
  566.      return ;
  567.  
  568.    if (!d->sur)  {
  569.      size = 8 + (sidsz+1)*(sidsz+1)*sizeof(TrigPoint) ;
  570.  
  571.      if (!(sur = (TrigPoint *) malloc(size)))  {
  572.        fprintf(stderr,"ERROR: malloc(%d) failed in create_continent()\n",size) ;
  573.        exit(0) ;
  574.        }
  575.  
  576.      hey = (uint32)sur ;
  577.      if (hey & 8)  {
  578.        hey = (hey + 8) & 0xfffffff0 ;
  579.        sur = (TrigPoint *) hey ;
  580.        d->quadw = 0 ;
  581.        }
  582.      else d->quadw = 1 ;
  583.  
  584.      p0 = sur ;
  585.      p1 = p0 + sidsz ;
  586.      p2 = sur + (sidsz+1)*sidsz ;
  587.      p3 = p2 + sidsz ;
  588.  
  589.      if (!even)  {
  590.        p0->plan = (d+0)->p ; 
  591.        p0->seed = (d+0)->seed ; 
  592.        p1->plan = (d+1)->p ; 
  593.        p1->seed = (d+1)->seed ; 
  594.        p2->plan = (d+33)->p ; 
  595.        p2->seed = (d+33)->seed ; 
  596.        p3->plan = (d+34)->p ; 
  597.        p3->seed = (d+34)->seed ; 
  598.        }
  599.      else  {
  600.        p0->plan = (d+1)->p ; 
  601.        p0->seed = (d+1)->seed ; 
  602.        p1->plan = (d+34)->p ; 
  603.        p1->seed = (d+34)->seed ; 
  604.        p2->plan = (d+0)->p ; 
  605.        p2->seed = (d+0)->seed ; 
  606.        p3->plan = (d+33)->p ; 
  607.        p3->seed = (d+33)->seed ; 
  608.        }
  609.  
  610.      p0->delta=fsqrt(p0->plan.x*p0->plan.x+p0->plan.y*p0->plan.y+p0->plan.z*p0->plan.z);
  611.      p1->delta=fsqrt(p1->plan.x*p1->plan.x+p1->plan.y*p1->plan.y+p1->plan.z*p1->plan.z);
  612.      p2->delta=fsqrt(p2->plan.x*p2->plan.x+p2->plan.y*p2->plan.y+p2->plan.z*p2->plan.z);
  613.      p3->delta=fsqrt(p3->plan.x*p3->plan.x+p3->plan.y*p3->plan.y+p3->plan.z*p3->plan.z);
  614.      }
  615.  
  616.    if (create)  {
  617.      if (create == BOTHH_TRI)
  618.        dbg[0] += 2 ;
  619.      else dbg[1]++ ;
  620.  
  621.      if (Counter.flags & FRACT_FLAG)
  622.        if (d->sur) {
  623.          p1 = d->sur + sidsz ;
  624.          p2 = d->sur + (sidsz+1)*sidsz ;
  625.  
  626.          if (!even)  {
  627.            p1->plan = (d+ 1)->p ; 
  628.            p2->plan = (d+33)->p ; 
  629.            }
  630.          else  {
  631.            p1->plan = (d+34)->p ; 
  632.            p2->plan = (d+ 0)->p ; 
  633.            }
  634.          }
  635.  
  636.      if (!d->sur)
  637.        d->sur = sur ;
  638.  
  639.      land_generation(d,create) ;
  640.  
  641.      if (Counter.flags & FRACT_FLAG)
  642.        water_conversion(d,create) ;
  643.  
  644.      generate_shades(d,create) ;
  645.      d->valid |= create ;
  646.      }
  647.    else if (!d->sur)  {
  648.      hey = (uint32)sur ;
  649.      free(hey - (d->quadw) ? 0 : 8) ;
  650.      }
  651. }
  652.  
  653. /**********************************************************************
  654. *  destroy_continent()  - 
  655. **********************************************************************/
  656. static void destroy_continent(register P5 *p)
  657.  
  658. {  register uint32 hey ;  
  659.  
  660.    if (p->sur)  {
  661.      hey = (uint32)p->sur ;
  662.  
  663.      free(hey - (p->quadw) ? 0 : 8) ;
  664.  
  665.      p->valid = 0 ;
  666.      p->quadw = 0 ;
  667.      p->sur = 0 ;
  668.      }
  669. }
  670.  
  671. /**********************************************************************
  672. *  land_generation()  -
  673. **********************************************************************/
  674. static void land_generation(P5 *d,register sint32 triflag)
  675.  
  676. {  register sint32    stage,step,dstep,i,j,s,q,sp ;
  677.    register flot32    x,y,z,w,rg ;
  678.    register TrigPoint *sur,*c,*c1,*c2,*c3,*c4 ;
  679.    register P4        p ;
  680.  
  681.    sur = d->sur ;
  682.  
  683.    step = 1 << (levels-1) ;
  684.    rg = roughness/((1.0+C)*16384.0) ;
  685.  
  686.    for (dstep=step+step,stage=1; stage<=levels; rg*=0.50,dstep=step,step>>=1,stage++)  {
  687.      sp = step*(sidsz+1) ;
  688.  
  689.      for (i=dstep; i<=sidsz; i+=dstep)  {
  690.        c1 = sur + i - dstep ; 
  691.        c2 = sur + i ; 
  692.        c3 = sur + dstep*(sidsz+1) + i - dstep ;
  693.        c4 = sur + dstep*(sidsz+1) + i ;
  694.  
  695.        for (j=step; j<=sidsz; j+=dstep)  {
  696.          q = sidsz + step - i - j ;
  697.  
  698.          if ((triflag & LOWER_TRI) && (q >= 0))  {
  699.            c = c2-step ;
  700.            SUBDIVIDE(c1,c2,c) ;
  701.            c = c1+sp ;
  702.            SUBDIVIDE(c1,c3,c) ;
  703.            c = c1+sp+step ;
  704.            SUBDIVIDE(c2,c3,c) ;
  705.            }
  706.  
  707.          if ((triflag & UPPER_TRI) && (q <= 0)) {
  708.            c = c4-step ;
  709.            SUBDIVIDE(c3,c4,c) ;
  710.            c = c2+sp ;
  711.            SUBDIVIDE(c2,c4,c) ;
  712.            c = c1+sp+step ;
  713.            SUBDIVIDE(c2,c3,c) ;
  714.            }
  715.  
  716.          c1 += sp+sp ;
  717.          c2 += sp+sp ;
  718.          c3 += sp+sp ;
  719.          c4 += sp+sp ;
  720.          }
  721.        }
  722.      }
  723. }
  724.  
  725. /**********************************************************************
  726. *  water_conversion()  - 
  727. **********************************************************************/
  728. static void water_conversion(register P5 *d,register sint32 triflag) 
  729.  
  730. {  register sint32    i,j,q ;
  731.    register flot32    a,b,w,m ;
  732.    register TrigPoint *sur,*trg ;
  733.  
  734.    sur = d->sur ;
  735.  
  736.    a = LEVEL_SEA ;
  737.    b = LEVEL_SNOW ;
  738.  
  739.    for (i=0; i<=sidsz; i++) 
  740.      for (trg=sur+(sidsz+1)*i,j=0; j<=sidsz; trg++,j++)  {
  741.        q = sidsz-i-j ;
  742.  
  743.        if (((triflag & LOWER_TRI) && (q >= 0)) || ((triflag & UPPER_TRI) && (q <= 0)))  {
  744.          w = trg->delta ;
  745.  
  746.          if (w <= a)  {
  747.            trg->plan.x /= w ;
  748.            trg->plan.y /= w ;
  749.            trg->plan.z /= w ;
  750.            }
  751.  
  752.          if (w > 1.0+(1.0 - 2.0*trg->plan.y*trg->plan.y)*roughness)
  753.            trg->label = MAT_WHITE ;
  754.          else if (w <= a)
  755.            trg->label = MAT_SEABLUE ;
  756.          else trg->label = MAT_DIRT ;
  757.          }
  758.        }
  759. }
  760.  
  761. /**********************************************************************
  762. *  generate_shades()  - 
  763. **********************************************************************/
  764. static void generate_shades(register P5 *d,register sint32 triflag) 
  765.  
  766. {  register sint32    i,j,r,g,b,q;
  767.    register flot32    x,y,z,w ;
  768.    register V3        v1,v2 ;
  769.    register TrigPoint *sur,*p00,*p10 ;
  770.    register C6        *cc,cl ;
  771.  
  772.    sur = d->sur ;
  773.  
  774.    for (i=0; i<sidsz; i++)  {
  775.       p00 = sur + (sidsz+1)*(i) ;
  776.       p10 = sur + (sidsz+1)*(i+1) ;
  777.  
  778.       for (j=0; j<sidsz; p00++,p10++,j++)  {
  779.         q = sidsz - i - j ;
  780.  
  781.         if (((triflag & LOWER_TRI) && (q >= 1)) || ((triflag & UPPER_TRI) && (q <= 0)))  {
  782.           v1.x = (p00+1)->plan.x - p00->plan.x ;
  783.           v1.y = (p00+1)->plan.y - p00->plan.y ;
  784.           v1.z = (p00+1)->plan.z - p00->plan.z ;
  785.  
  786.           v2.x = p10->plan.x - p00->plan.x ;
  787.           v2.y = p10->plan.y - p00->plan.y ;
  788.           v2.z = p10->plan.z - p00->plan.z ;
  789.        
  790.           x = v2.y * v1.z - v1.y * v2.z ;
  791.           y = v1.x * v2.z - v2.x * v1.z ;
  792.           z = v2.x * v1.y - v1.x * v2.y ;
  793.           w = x*lit.x + y*lit.y + z*lit.z ;
  794.  
  795.           if (Counter.flags & FRACT_FLAG)  {
  796.             r = p00->label + (p00+1)->label + p10->label ;
  797.             if (r == SUM_SEABLUE)
  798.               cc = &a_seab ;
  799.             else if (r == SUM_WHITE)
  800.               cc = &a_whit ;
  801.             else cc = &a_dirt ;
  802.  
  803.             r = cc->ar ;
  804.             g = cc->ag ;
  805.             b = cc->ab ;
  806.  
  807.             if (w > 0.0)  {
  808.               w /= fsqrt(x*x+y*y+z*z) ;
  809.               r += cc->dr * w;
  810.               g += cc->dg * w;
  811.               b += cc->db * w;
  812.               }
  813.             }
  814.           else  {
  815.             cl.dr = ((p00->seed    ) & 0xff) + (((p00+1)->seed    ) & 0xff) + ((p10->seed    ) & 0xff) ;
  816.             cl.dg = ((p00->seed>> 8) & 0xff) + (((p00+1)->seed>> 8) & 0xff) + ((p10->seed>> 8) & 0xff) ;
  817.             cl.db = ((p00->seed>>16) & 0xff) + (((p00+1)->seed>>16) & 0xff) + ((p10->seed>>16) & 0xff) ;
  818.             r = 0.015 * cl.dr ;
  819.             g = 0.015 * cl.dg ;
  820.             b = 0.015 * cl.db ;
  821.  
  822.             if (w > 0.0)  {
  823.               w /= (3.0*fsqrt(x*x+y*y+z*z)) ;
  824.               r += cl.dr * w;
  825.               g += cl.dg * w;
  826.               b += cl.db * w;
  827.               }
  828.             }
  829.  
  830.           p00->cpack1 = (r<<24) | (g<<16) | (b<<8) | 0xff ;
  831.           }
  832.  
  833.         if (((triflag & LOWER_TRI) && (q > 1)) || ((triflag & UPPER_TRI) && (q <= 1)))  {
  834.           v1.x = p10->plan.x - (p10+1)->plan.x ;
  835.           v1.y = p10->plan.y - (p10+1)->plan.y ;
  836.           v1.z = p10->plan.z - (p10+1)->plan.z ;
  837.  
  838.           v2.x = (p00+1)->plan.x - (p10+1)->plan.x ;
  839.           v2.y = (p00+1)->plan.y - (p10+1)->plan.y ;
  840.           v2.z = (p00+1)->plan.z - (p10+1)->plan.z ;
  841.  
  842.           x = v2.y * v1.z - v1.y * v2.z ;
  843.           y = v1.x * v2.z - v2.x * v1.z ;
  844.           z = v2.x * v1.y - v1.x * v2.y ;
  845.           w = x*lit.x + y*lit.y + z*lit.z ;
  846.  
  847.           if (Counter.flags & FRACT_FLAG)  {
  848.             r = (p10+1)->label + (p00+1)->label + p10->label ;
  849.             if (r == SUM_SEABLUE)
  850.               cc = &a_seab ;
  851.             else if (r == SUM_WHITE)
  852.               cc = &a_whit ;
  853.             else cc = &a_dirt ;
  854.  
  855.             r = cc->ar ;
  856.             g = cc->ag ;
  857.             b = cc->ab ;
  858.  
  859.             if (w > 0.0)  {
  860.               w /= fsqrt(x*x+y*y+z*z) ;
  861.               r += cc->dr * w;
  862.               g += cc->dg * w;
  863.               b += cc->db * w;
  864.               }
  865.             }
  866.           else  {
  867.             cl.dr = (((p10+1)->seed    ) & 0xff) + (((p00+1)->seed    ) & 0xff) + ((p10->seed    ) & 0xff) ;
  868.             cl.dg = (((p10+1)->seed>> 8) & 0xff) + (((p00+1)->seed>> 8) & 0xff) + ((p10->seed>> 8) & 0xff) ;
  869.             cl.db = (((p10+1)->seed>>16) & 0xff) + (((p00+1)->seed>>16) & 0xff) + ((p10->seed>>16) & 0xff) ;
  870.             r = 0.015 * cl.dr ;
  871.             g = 0.015 * cl.dg ;
  872.             b = 0.015 * cl.db ;
  873.  
  874.             if (w > 0.0)  {
  875.               w /= (3.0*fsqrt(x*x+y*y+z*z)) ;
  876.               r += cl.dr * w;
  877.               g += cl.dg * w;
  878.               b += cl.db * w;
  879.               }
  880.             }
  881.  
  882.           p00->cpack2 = (r<<24) | (g<<16) | (b<<8) | 0xff ;
  883.           }
  884.         }
  885.       }
  886. }
  887.  
  888. /**********************************************************************
  889. *  bound_normals()  - 
  890. **********************************************************************/
  891. static void bound_normals(P3 *p0,P3 *p1,P3 *p2,V4 *v)
  892.  
  893. {  register flot32  x,y,z,w ;
  894.    register V4      v1,v2 ;
  895.  
  896.    x = p1->y * p0->z - p0->y * p1->z ;
  897.    y = p0->x * p1->z - p1->x * p0->z ;
  898.    z = p1->x * p0->y - p0->x * p1->y ;
  899.    w = -(x*p0->x + y*p0->y + z*p0->z) ;
  900.    if (x*p2->x + y*p2->y + z*p2->z + w < 0.0)
  901.      { x = -x ; y = -y ; z = -z ; w = -w ; }
  902.    v[0].x = x ; v[0].y = y ; v[0].z = z ; v[0].w = w ; 
  903.  
  904.    x = p2->y * p1->z - p1->y * p2->z ;
  905.    y = p1->x * p2->z - p2->x * p1->z ;
  906.    z = p2->x * p1->y - p1->x * p2->y ;
  907.    w = -(x*p1->x + y*p1->y + z*p1->z) ;
  908.    if (x*p0->x + y*p0->y + z*p0->z + w < 0.0)
  909.      { x = -x ; y = -y ; z = -z ; w = -w ; }
  910.    v[1].x = x ; v[1].y = y ; v[1].z = z ; v[1].w = w ; 
  911.  
  912.    x = p0->y * p2->z - p2->y * p0->z ;
  913.    y = p2->x * p0->z - p0->x * p2->z ;
  914.    z = p0->x * p2->y - p2->x * p0->y ;
  915.    w = -(x*p2->x + y*p2->y + z*p2->z) ;
  916.    if (x*p1->x + y*p1->y + z*p1->z + w < 0.0)
  917.      { x = -x ; y = -y ; z = -z ; w = -w ; }
  918.    v[2].x = x ; v[2].y = y ; v[2].z = z ; v[2].w = w ; 
  919.  
  920.    v1.x = p2->x - p0->x ; 
  921.    v1.y = p2->y - p0->y ; 
  922.    v1.z = p2->z - p0->z ; 
  923.  
  924.    v2.x = p1->x - p0->x ; 
  925.    v2.y = p1->y - p0->y ; 
  926.    v2.z = p1->z - p0->z ; 
  927.  
  928.    x = v2.y * v1.z - v1.y * v2.z ;
  929.    y = v1.x * v2.z - v2.x * v1.z ;
  930.    z = v2.x * v1.y - v1.x * v2.y ;
  931.    w = fsqrt(x*x+y*y+z*z) ;
  932.    x /= w ; y /= w ; z /= w ;
  933.    w = -(x*p2->x + y*p2->y + z*p2->z) ;
  934.    v[3].x = x ; v[3].y = y ; v[3].z = z ; v[3].w = w ; 
  935.  
  936.    x = p0->x + p1->x + p2->x ;
  937.    y = p0->y + p1->y + p2->y ;
  938.    z = p0->z + p1->z + p2->z ;
  939.    w = fsqrt(x*x+y*y+z*z) ;
  940.    v[4].x = x/w ; v[4].y = y/w ; v[4].z = z/w ; v[4].w = 0.0 ; 
  941. }
  942.  
  943. /**********************************************************************
  944. *  clipp()  -
  945. **********************************************************************/
  946. static sint32 clipp(register P5 *d)
  947.  
  948. {  register sint32 i,j ;
  949.    register uint32 flag,resu,mask ;
  950.    register P3     *p ; 
  951.    register V4     *c ; 
  952.  
  953.    for (c=plum,resu=i=0; i<NUM_CLIP_PLANES; c++,i++)  {
  954.      for (mask=1,p=d->pp,flag=0,j=0; j<8; mask<<=1,p++,j++)
  955.        if (c->x*p->x + c->y*p->y + c->z*p->z + c->w < 0.0)
  956.          flag |= mask ;
  957.  
  958.      if (flag == 0xff)
  959.        return(0) ; 
  960.      if ((flag&0x3f) == 0x3f) 
  961.        resu |= LOWER_TRI ;
  962.      if ((flag&0xfc) == 0xfc)
  963.        resu |= UPPER_TRI ;
  964.      }
  965.  
  966.    return(~resu & BOTHH_TRI) ;
  967. }
  968.  
  969. /**********************************************************************
  970. *  cpack_continent()  -
  971. **********************************************************************/
  972. static void cpack_continent(P5 *d,uint32 flag)
  973.  
  974. {  register sint32     i,j ;
  975.    register TrigPoint  *trp,*trq,*srp,*srq ;
  976.  
  977.    if ((uint32)d->sur & 0x0f)  {
  978.      printf("Error: data is not quad-word aligned: 0x%08x!\n",d->sur) ;
  979.      exit() ;
  980.      }
  981.  
  982.    switch (flag)  {
  983.      case         0 : return ;
  984.                       break ;
  985.  
  986.      case BOTHH_TRI : for (srp=d->sur,srq=srp+sidsz+1,j=sidsz; j>0; srp=srq,srq+=sidsz+1,j--)  {
  987.                         glBegin(GL_TRIANGLE_STRIP) ;
  988.                         glVertex3fv(&srp->plan.x) ;
  989.                         glVertex3fv(&srq->plan.x) ;
  990.                  
  991.                         for (trp=srp,trq=srq+1,i=sidsz; i>0; trp++,trq++,i--)  {
  992.                           glColor4ubv((unsigned char*)&trp->cpack1) ;
  993.                           glVertex3fv(&(trp+1)->plan.x) ;
  994.                  
  995.                           glColor4ubv((unsigned char*)&trp->cpack2) ;
  996.                           glVertex3fv(&trq->plan.x) ;
  997.                           }
  998.                         glEnd() ;
  999.                         }
  1000.  
  1001.                       dbg[2]+=2 ;
  1002.                       break ;
  1003.  
  1004.      case LOWER_TRI : for (srp=d->sur,j=sidsz; j>0; srp+=sidsz+1,j--)  {
  1005.                         glBegin(GL_TRIANGLE_STRIP) ;
  1006.                         glVertex3fv(&srp->plan.x) ;
  1007.                         glVertex3fv(&(srp+sidsz+1)->plan.x) ;
  1008.                  
  1009.                         for (trp=srp,i=j-1; i>0; i--)  {
  1010.                           glColor4ubv((unsigned char*)&trp->cpack1) ;
  1011.                           glVertex3fv(&(trp+1)->plan.x) ;
  1012.                  
  1013.                           glColor4ubv((unsigned char*)&trp->cpack2) ;
  1014.                           glVertex3fv(&(trp+sidsz+2)->plan.x) ;
  1015.                           trp++ ;
  1016.                           }
  1017.                  
  1018.                         glColor4ubv((unsigned char*)&trp->cpack1) ;
  1019.                         glVertex3fv(&(trp+1)->plan.x) ;
  1020.                         glEnd() ;
  1021.                         }
  1022.  
  1023.                       dbg[3]++ ;
  1024.                       break ;
  1025.  
  1026.      case UPPER_TRI : for (srp=(d->sur+(sidsz+1)*sidsz+sidsz),j=sidsz; j>0; srp-=sidsz+1,j--)  {
  1027.                         glBegin(GL_TRIANGLE_STRIP) ;
  1028.                         glVertex3fv(&srp->plan.x) ;
  1029.                         glVertex3fv(&(srp-sidsz-1)->plan.x) ;
  1030.                  
  1031.                         for (trp=srp,i=j-1; i>0; i--)  {
  1032.                           glColor4ubv((unsigned char*)&(trp-sidsz-2)->cpack2) ;
  1033.                           glVertex3fv(&(trp-1)->plan.x) ;
  1034.                  
  1035.                           glColor4ubv((unsigned char*)&(trp-sidsz-2)->cpack1) ;
  1036.                           glVertex3fv(&(trp-sidsz-2)->plan.x) ;
  1037.                           trp-- ;
  1038.                           }
  1039.                  
  1040.                         glColor4ubv((unsigned char*)&(trp-sidsz-2)->cpack2) ;
  1041.                         glVertex3fv(&(trp-1)->plan.x) ;
  1042.                         glEnd() ;
  1043.                         }
  1044.  
  1045.                       dbg[3]++ ;
  1046.                       break ;
  1047.  
  1048.      default        : printf("Error: cpack_continent(%d)\n",flag) ;
  1049.                       exit(0) ;
  1050.                       break ;
  1051.      }
  1052. }
  1053.  
  1054. /**********************************************************************
  1055. *  enhanced_bound_normals()  -
  1056. **********************************************************************/
  1057. static void enhanced_bound_normals(register P5 *d,register sint32 triflag)
  1058.  
  1059. {  register sint32    i,j ;
  1060.    register TrigPoint *sur,*c0 ;
  1061.    register Bounder   *z0 ;
  1062.  
  1063.    sur = d->sur ;
  1064.  
  1065.    if (triflag == LOWER_TRI)
  1066.      for (i=0; i<sidsz; i++)
  1067.        for (j=0; j<sidsz-i; j++)  {
  1068.          c0 = sur + i*(sidsz+1) + j ;
  1069.          z0 = &checkcrash[i][j] ;
  1070.  
  1071.          bound_normals(&c0->plan,&(c0+sidsz+1)->plan,&(c0+1)->plan,&z0->v1[0]) ;
  1072.   
  1073.          if (i+j < sidsz-1)
  1074.            bound_normals(&(c0+sidsz+2)->plan,&(c0+1)->plan,&(c0+sidsz+1)->plan,&z0->v2[0]) ;
  1075.          }
  1076.    else  {
  1077.      for (i=0; i<sidsz; i++) 
  1078.        for (j=0; j<sidsz-i; j++)  {
  1079.          c0 = sur + (sidsz-i)*(sidsz+1) + sidsz - j ;
  1080.          z0 = &checkcrash[i][j] ;
  1081.  
  1082.          bound_normals(&c0->plan,&(c0-sidsz-1)->plan,&(c0-1)->plan,&z0->v1[0]) ;
  1083.   
  1084.          if (i+j < sidsz-1)
  1085.            bound_normals(&(c0-sidsz-2)->plan,&(c0-1)->plan,&(c0-sidsz-1)->plan,&z0->v2[0]) ;
  1086.          }
  1087.      }
  1088. }
  1089.  
  1090. /**********************************************************************
  1091. *  intersect_continent()  -
  1092. **********************************************************************/
  1093. static void intersect_continent(void) 
  1094.  
  1095. {  register sint32  i,j,crash ;
  1096.    register Bounder *bnd ;
  1097.    register flot32  x,y,z ;
  1098.    static   sint32  flag ;
  1099.  
  1100.    if (feye.w > 1.5)
  1101.      return ;
  1102.  
  1103.    x = feye.x ;
  1104.    y = feye.y ;
  1105.    z = feye.z ;
  1106.  
  1107.    for (crash=i=0; i<sidsz; i++)  {
  1108.       bnd = checkcrash[i] ;
  1109.  
  1110.       for (j=0; j<sidsz-i; bnd++,j++)  {
  1111.          if (bnd->v1[0].x*x + bnd->v1[0].y*y + bnd->v1[0].z*z + bnd->v1[0].w >= 0.0)
  1112.            if (bnd->v1[1].x*x + bnd->v1[1].y*y + bnd->v1[1].z*z + bnd->v1[1].w >= 0.0)
  1113.              if (bnd->v1[2].x*x + bnd->v1[2].y*y + bnd->v1[2].z*z + bnd->v1[2].w >= 0.0)  {
  1114.                if (bnd->v1[3].x*x + bnd->v1[3].y*y + bnd->v1[3].z*z + bnd->v1[3].w <= 0.0)
  1115.                  crash = 1 ;
  1116.                goto INTERSECT_END ;
  1117.                }
  1118.  
  1119.          if (i+j < sidsz-1)   {
  1120.            if (bnd->v2[0].x*x + bnd->v2[0].y*y + bnd->v2[0].z*z + bnd->v2[0].w >= 0.0)
  1121.              if (bnd->v2[1].x*x + bnd->v2[1].y*y + bnd->v2[1].z*z + bnd->v2[1].w >= 0.0)
  1122.                if (bnd->v2[2].x*x + bnd->v2[2].y*y + bnd->v2[2].z*z + bnd->v2[2].w >= 0.0)  {
  1123.                  if (bnd->v2[3].x*x + bnd->v2[3].y*y + bnd->v2[3].z*z + bnd->v2[3].w <= 0.0)
  1124.                    crash = 2 ;
  1125.                  goto INTERSECT_END ;
  1126.                  }
  1127.            }
  1128.          }
  1129.       }
  1130.  
  1131. INTERSECT_END :
  1132.    if (crash)  {
  1133.      register t_body *tb;
  1134.      extern t_boss flaggs;
  1135.  
  1136.      spRingBell() ;
  1137.  
  1138.      tb = (t_body *) flaggs.star[flaggs.suun_current].next[flaggs.plan_current] ;
  1139.      x = fsqrt(tb->posit.x*tb->posit.x+tb->posit.y*tb->posit.y+tb->posit.z*tb->posit.z) ;
  1140.  
  1141.      Counter.eye.x -= (tb->posit.x + 16.0)/x;
  1142.      Counter.eye.y -= (tb->posit.y + 16.0)/x;
  1143.      Counter.eye.z -= (tb->posit.z + 16.0)/x;
  1144.      }
  1145. }
  1146.  
  1147. /**********************************************************************
  1148. *  p_trigpoint()  -
  1149. **********************************************************************/
  1150. static void p_trigpoint(TrigPoint *t) 
  1151.  
  1152. {
  1153.    printf("T: %7.4f %7.4f %7.4f %6.4f %06d %1d 0x%08x 0x%08x\n",
  1154.               t->plan.x,t->plan.y,t->plan.z,t->delta,t->seed,t->label,t->cpack1,t->cpack2) ;
  1155. }
  1156.  
  1157. /**********************************************************************
  1158. *  p_continent()  -
  1159. **********************************************************************/
  1160. static void p_continent(register P5 *d) 
  1161.  
  1162. {  sint32 i,j ;
  1163.  
  1164.    printf("Continent: 0x%08x\n",d->sur) ;
  1165.  
  1166.    for (i=0; i<=sidsz; i++)
  1167.      for (j=0; j<=sidsz; j++)  {
  1168.         printf("%d %d:",i,j) ;
  1169.         p_trigpoint(d->sur + i*(sidsz+1) + j) ;
  1170.         }
  1171. }
  1172.  
  1173.